package com.example.padlock.view.sendvedio;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class VedioSender implements SurfaceHolder.Callback{

	private static final String tag = "VedioSender";
	private boolean sending = true;
	private SurfaceHolder holder;
	private SurfaceView surfaceView;
	private Socket sendSocket = null;
	private String serverURL;
	private OutputStream socketOuts=null;
	private int serverPort;
	private ConnectThread connectThread = null;
	private Camera camera;
	private int screenWidth = 640;
	private int screenHeight = 480;
	public  boolean isSend=false;
	
	/**
	 * @param sur a surfaceView
	 */
	public VedioSender(SurfaceView sur,ConnectThread thread){
		surfaceView = sur;
		holder = surfaceView.getHolder();
		holder.addCallback(this);
		this.connectThread =thread;
	}
	
	
	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		try {
			cameraInit();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		if (camera != null) {
			camera.setPreviewCallback(null);
			camera.stopPreview();
			camera.release();
			camera = null;
		}
	    //System.exit(0);
	}
	
	
	/**
	 * ����ͷ��ʼ��
	 * */
	private void cameraInit() throws IOException{
		Log.e(tag, "start cameraInit");
		camera = Camera.open();
		Camera.Parameters parameters = camera.getParameters();				
		parameters.setPreviewSize(screenWidth, screenHeight);    // ����Ԥ����Ƭ�Ĵ�С				
	//	parameters.setPreviewFpsRange(10,15);                    // ÿ����ʾ20~30֡				
	//	parameters.setPictureFormat(ImageFormat.NV21);           // ����ͼƬ��ʽ	nv21
	//	parameters.setPreviewFormat(ImageFormat.NV21);//???
		parameters.setPictureSize(screenWidth, screenHeight);    // ������Ƭ�Ĵ�С
		camera.setParameters(parameters);                      // android2.3.3�Ժ���Ҫ���д���

		camera.setDisplayOrientation(90);
		camera.setPreviewDisplay(holder);                 // ͨ��SurfaceView��ʾȡ������				
        camera.setPreviewCallback(new StreamIt());         // ���ûص�����				
		camera.startPreview();                                   // ��ʼԤ��				
		camera.autoFocus(null);
	}
	
	class StreamIt implements Camera.PreviewCallback{
		ByteArrayOutputStream outstream;
		ByteArrayInputStream bis;
		int tempCount = 0;
		byte[] buf = new byte[2048];
		
		@Override
		public void onPreviewFrame(byte[] data, Camera camera) {
			// TODO Auto-generated method stub
			
//			if(!connectThread.isConnect)
//				return;
//			if(!isSend){
//				return;
//			}
			if(!connectThread.isSendAble()){
				return;
			}
			System.out.println("sending.......");
			Size size = camera.getParameters().getPreviewSize();          
	        try{ 
	            YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);  
	            if(image!=null){
	            	outstream = new ByteArrayOutputStream();
	                image.compressToJpeg(new Rect(0, 0, size.width, size.height), 15, outstream); 
	                outstream.flush();
	            }
	            byte[] databuf = outstream.toByteArray();
	            int amount = 0;
	            bis = new ByteArrayInputStream(databuf);
				
				while((tempCount=bis.read(buf))>0){
					amount+=tempCount;
					if(connectThread!=null)
						connectThread.write(buf, 0, tempCount);
					System.out.println("image:"+buf.toString());
				}
//				if(socketOuts!=null)
//				socketOuts.flush();
				if(amount==databuf.length){
					Log.i(tag,"send a jpg ok!");
				}
				else {
//					sending = false;
					Log.e(tag,"send a jpg fail!");
				}
				bis.close();
				outstream.close();
	            Thread.sleep(50);//20fps
	            
	        }catch(Exception ex){  
//	        	sending = false;
	        	try {
					bis.close();
					outstream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	            Log.e("Sys","Error:"+ex.getMessage());  
	        }
			
		}
		
	}
	
	
	/**
	 * start to send vedio data.(build connect and write data).
	 * @param host the target host.
	 * @param port the target port.
	 * @return Block until sending is stopped
	 */
	
	public void send(OutputStream os){
		this.socketOuts=os;
	}
	public void send(String host,int port){
		serverURL = host;
		serverPort = port;
		connectThread.start();
		while(sending);
			return;
	}
	
	public void stop(){
		try {	
			if(sendSocket!=null){
				sendSocket.close();
				sendSocket = null;
			}
			if(socketOuts!=null){
				socketOuts.close();
				socketOuts = null;
			}
			sending = false;
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
//	private class ConnectThread extends Thread{
//		private static final String tag = "ConnectThread";
//		public boolean isConnect = false;
//		@Override
//		public void run() {
//			try {
//				sendSocket = new Socket(serverURL, serverPort);
//				socketOuts = sendSocket.getOutputStream();
//				isConnect = true;
//				Log.i(tag,"get socketOustream! isConnect=true");
//			} catch (UnknownHostException e) {
//				try {	
//					Log.e(tag,"wrong! can't build connection!");
//					if(sendSocket!=null){
//						sendSocket.close();
//						sendSocket = null;
//					}
//					if(socketOuts!=null){
//						socketOuts.close();
//						socketOuts = null;
//					}
//					sending = false;
//					
//				}catch (IOException e1) {
//					// TODO Auto-generated catch block
//					e1.printStackTrace();
//				}
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//	}
//	
//	
//	
	
	
}
